home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 16 / CU Amiga Magazine's Super CD-ROM 16 (1997-10-16)(EMAP Images)(GB)[!][issue 1997-11].iso / CUCD / Graphics / Ghostscript / source / iutil.c < prev    next >
C/C++ Source or Header  |  1997-07-08  |  17KB  |  600 lines

  1. /* Copyright (C) 1989, 1995, 1996, 1997 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of Aladdin Ghostscript.
  4.   
  5.   Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
  9.   License (the "License") for full details.
  10.   
  11.   Every copy of Aladdin Ghostscript must include a copy of the License,
  12.   normally in a plain ASCII text file named PUBLIC.  The License grants you
  13.   the right to copy, modify and redistribute Aladdin Ghostscript, but only
  14.   under certain conditions described in the License.  Among other things, the
  15.   License requires that the copyright notice and this notice be preserved on
  16.   all copies.
  17. */
  18.  
  19. /* iutil.c */
  20. /* Utilities for Ghostscript interpreter */
  21. #include "math_.h"            /* for fabs */
  22. #include "memory_.h"
  23. #include "string_.h"
  24. #include "ghost.h"
  25. #include "errors.h"
  26. #include "idict.h"
  27. #include "imemory.h"
  28. #include "iname.h"
  29. #include "ipacked.h"            /* for array_get */
  30. #include "iutil.h"            /* for checking prototypes */
  31. #include "ivmspace.h"
  32. #include "oper.h"
  33. #include "store.h"
  34. #include "gsccode.h"            /* for gxfont.h */
  35. #include "gsmatrix.h"
  36. #include "gsutil.h"
  37. #include "gxfont.h"
  38.  
  39. /* ------ Object utilities ------ */
  40.  
  41. /* Copy refs from one place to another. */
  42. int
  43. refcpy_to_old(ref *aref, uint index, register const ref *from,
  44.   register uint size, client_name_t cname)
  45. {    register ref *to = aref->value.refs + index;
  46.     int code = refs_check_space(from, size, r_space(aref));
  47.     if ( code < 0 )
  48.         return code;
  49.     /* We have to worry about aliasing.... */
  50.     if ( to <= from || from + size <= to )
  51.         while ( size-- )
  52.             ref_assign_old(aref, to, from, cname), to++, from++;
  53.     else
  54.         for ( from += size, to += size; size--; )
  55.             from--, to--, ref_assign_old(aref, to, from, cname);
  56.     return 0;
  57. }
  58. void
  59. refcpy_to_new(register ref *to, register const ref *from, register uint size)
  60. {    while ( size-- )
  61.         ref_assign_new(to, from), to++, from++;
  62. }
  63.  
  64. /* Fill a new object with nulls. */
  65. void
  66. refset_null(register ref *to, register uint size)
  67. {    while ( size-- ) make_null_new(to), to++;
  68. }
  69.  
  70. /* Compare two objects for equality. */
  71. bool
  72. obj_eq(register const ref *pref1, register const ref *pref2)
  73. {    ref nref;
  74.     if ( r_type(pref1) != r_type(pref2) )
  75.        {    /* Only a few cases need be considered here: */
  76.         /* integer/real (and vice versa), name/string */
  77.         /* (and vice versa), and extended operators. */
  78.         switch ( r_type(pref1) )
  79.            {
  80.         case t_integer:
  81.             return (r_has_type(pref2, t_real) &&
  82.                 pref2->value.realval == pref1->value.intval);
  83.         case t_real:
  84.             return (r_has_type(pref2, t_integer) &&
  85.                 pref2->value.intval == pref1->value.realval);
  86.         case t_name:
  87.             if ( !r_has_type(pref2, t_string) )
  88.               return false;
  89.             name_string_ref(pref1, &nref);
  90.             pref1 = &nref;
  91.             break;
  92.         case t_string:
  93.             if ( !r_has_type(pref2, t_name) )
  94.               return false;
  95.             name_string_ref(pref2, &nref);
  96.             pref2 = &nref;
  97.             break;
  98.         default:
  99.             if ( r_btype(pref1) != r_btype(pref2) )
  100.               return false;
  101.            }
  102.        }
  103.     /* Now do a type-dependent comparison. */
  104.     /* This would be very simple if we always filled in */
  105.     /* all 8 bytes of a ref, but we currently don't. */
  106.     switch ( r_btype(pref1) )
  107.        {
  108.     case t_array:
  109.         return (pref1->value.refs == pref2->value.refs &&
  110.             r_size(pref1) == r_size(pref2));
  111.     case t_mixedarray:
  112.     case t_shortarray:
  113.         return (pref1->value.packed == pref2->value.packed &&
  114.             r_size(pref1) == r_size(pref2));
  115.     case t_boolean:
  116.         return (pref1->value.boolval == pref2->value.boolval);
  117.     case t_dictionary:
  118.         return (pref1->value.pdict == pref2->value.pdict);
  119.     case t_file:
  120.         return (pref1->value.pfile == pref2->value.pfile &&
  121.             r_size(pref1) == r_size(pref2));
  122.     case t_integer:
  123.         return (pref1->value.intval == pref2->value.intval);
  124.     case t_mark:
  125.     case t_null:
  126.         return true;
  127.     case t_name:
  128.         return (pref1->value.pname == pref2->value.pname);
  129.     case t_oparray:
  130.     case t_operator:
  131.         return (op_index(pref1) == op_index(pref2));
  132.     case t_real:
  133.         return (pref1->value.realval == pref2->value.realval);
  134.     case t_save:
  135.         return (pref2->value.saveid == pref1->value.saveid);
  136.     case t_string:
  137.         return (!bytes_compare(pref1->value.bytes, r_size(pref1),
  138.                        pref2->value.bytes, r_size(pref2)));
  139.     case t_device:
  140.         return (pref1->value.pdevice == pref2->value.pdevice);
  141.     case t_struct:
  142.     case t_astruct:
  143.         return (pref1->value.pstruct == pref2->value.pstruct);
  144.     case t_fontID:
  145.       {    /*
  146.          * In the Adobe implementations, different scalings of a
  147.          * font have "equal" FIDs, so we do the same.
  148.          */
  149.         const gs_font *pfont1 = r_ptr(pref1, gs_font);
  150.         const gs_font *pfont2 = r_ptr(pref2, gs_font);
  151.  
  152.         while ( pfont1->base != pfont1 )
  153.           pfont1 = pfont1->base;
  154.         while ( pfont2->base != pfont2 )
  155.           pfont2 = pfont2->base;
  156.         return (pfont1 == pfont2);
  157.       }
  158.       }
  159.     return false;            /* shouldn't happen! */
  160. }
  161.  
  162. /* Compare two objects for identity. */
  163. bool
  164. obj_ident_eq(register const ref *pref1, register const ref *pref2)
  165. {    if ( r_type(pref1) != r_type(pref2) )
  166.       return false;
  167.     if ( r_has_type(pref1, t_string) )
  168.       return (pref1->value.bytes == pref2->value.bytes &&
  169.           r_size(pref1) == r_size(pref2));
  170.     return obj_eq(pref1, pref2);
  171. }
  172.  
  173. /*
  174.  * Create a printable representation of an object, a la cvs (full_print =
  175.  * false) or == (full_print = true).  Return 0 if OK, <0 if the destination
  176.  * wasn't large enough or the object's contents weren't readable.
  177.  * If the object was a string or name, store a pointer to its characters
  178.  * even if it was too large.
  179.  */
  180. int
  181. obj_cvp(const ref *op, byte *str, uint len, uint *prlen, const byte **pchars,
  182.   bool full_print)
  183. {    char buf[30];            /* big enough for any float */
  184.     const byte *pstr = (const byte *)buf;
  185.     uint plen;
  186.     ref nref;
  187.  
  188.     if ( full_print )
  189.       switch ( r_btype(op))
  190.         {
  191.         case t_boolean:
  192.         case t_integer:
  193.         case t_real:
  194.         break;
  195.         default:
  196.         return_error(e_typecheck);
  197.         }
  198.     switch ( r_btype(op) )
  199.        {
  200.     case t_boolean:
  201.         pstr = (const byte *)(op->value.boolval ? "true" : "false");
  202.         break;
  203.     case t_integer:
  204.         sprintf(buf, "%ld", op->value.intval);
  205.         break;
  206.     case t_name:
  207.         name_string_ref(op, &nref);    /* name string */
  208. cvname:        pstr = nref.value.bytes;
  209.         plen = r_size(&nref);
  210.         if ( pchars != 0 )
  211.           *pchars = pstr;
  212.         goto nl;
  213.     case t_oparray:
  214.         { uint index = op_index(op);
  215.           const op_array_table *opt = op_index_op_array_table(index);
  216.           name_index_ref(opt->nx_table[index - opt->base_index], &nref);
  217.         }
  218.         name_string_ref(&nref, &nref);
  219.         goto cvname;
  220.     case t_operator:
  221.        {    /* Recover the name from the initialization table. */
  222.         uint index = op_index(op);
  223.         /* Check the validity of the index.  (An out-of-bounds */
  224.         /* index is only possible when examining an invalid */
  225.         /* object using the debugger.) */
  226.         if ( index > 0 && index < op_def_count )
  227.            {    pstr = (const byte *)(op_def_table[index]->oname + 1);
  228.             break;
  229.            }
  230.        }
  231.         /* Internal operator, no name. */
  232.         sprintf(buf, "@0x%lx", (ulong)op->value.opproc);
  233.         break;
  234.     case t_real:
  235.         /*
  236.          * To get fully accurate output results for IEEE single-
  237.          * precision floats (24 bits of mantissa), the ANSI
  238.          * %g default of 6 digits is not enough; 9 are needed.
  239.          * Unfortunately, using %.9g for floats (as opposed to
  240.          * doubles) produces unfortunate artifacts such as 0.01 5 mul
  241.          * printing as 0.049999997.  Therefore, we print using %g,
  242.          * and if the result isn't accurate enough, print again
  243.          * using %.9g.  Unfortunately, a few PostScript programs
  244.          * 'know' that the printed representation of floats fits
  245.          * into 6 digits (e.g., with cvs).  We resolve this by letting
  246.          * cvs, cvrs, and = do what the Adobe interpreters appear
  247.          * to do (use %g), and only produce accurate output for ==,
  248.          * for which there is no analogue of cvs.  What a hack!
  249.          */
  250.         { float value = op->value.realval;
  251.           sprintf(buf, "%g", value);
  252.           if ( full_print )
  253.             {    float scanned;
  254.             sscanf(buf, "%f", &scanned);
  255.             if ( scanned != value )
  256.               sprintf(buf, "%.9g", value);
  257.             }
  258.         }
  259.         /*
  260.          * Make sure the output has a decimal point.
  261.          * This is needed for compatibility with
  262.          * Adobe (and other) interpreters.
  263.          */
  264.         if ( strchr(buf, '.') != NULL ) break;
  265.         {    char *ept = strchr(buf, 'e');
  266.             if ( ept == NULL )
  267.                 strcat(buf, ".0");
  268.             else
  269.             {    /* Insert the .0 before the exponent. */
  270.                 /* What a nuisance! */
  271.                 char buf1[30];
  272.                 strcpy(buf1, ept);
  273.                 strcpy(ept, ".0");
  274.                 strcat(buf, buf1);
  275.             }
  276.         }
  277.         break;
  278.     case t_string:
  279.         check_read(*op);
  280.         pstr = op->value.bytes;
  281.         plen = r_size(op);
  282.         if ( pchars != 0 )
  283.           *pchars = pstr;
  284.         goto nl;
  285.     default:
  286.         pstr = (const byte *)"--nostringval--";
  287.        }
  288.     plen = strlen((const char *)pstr);
  289. nl:    *prlen = plen;
  290.     if ( plen > len )
  291.       return_error(e_rangecheck);
  292.     memcpy(str, pstr, plen);
  293.     return 0;
  294. }
  295.  
  296. /* Find the index of an operator that doesn't have one stored in it. */
  297. ushort
  298. op_find_index(const ref *pref /* t_operator */)
  299. {    op_proc_p proc = real_opproc(pref);
  300.     register const op_def_ptr *opp = op_def_table;
  301.     register const op_def_ptr *opend = opp + op_def_count;
  302.     for ( ; ++opp < opend; )
  303.     {    if ( (*opp)->proc == proc )
  304.             return opp - op_def_table;
  305.     }
  306.     /* Lookup failed!  This isn't possible.... */
  307.     return 0;
  308. }
  309.  
  310. /*
  311.  * Convert an operator index to an operator or oparray ref.
  312.  * This is only used for debugging and for 'get' from packed arrays,
  313.  * so it doesn't have to be very fast.
  314.  */
  315. void
  316. op_index_ref(uint index, ref *pref)
  317. {    const op_array_table *opt;
  318.     if ( op_index_is_operator(index) )
  319.       {    make_oper(pref, index, op_index_proc(index));
  320.         return;
  321.       }
  322.     opt = op_index_op_array_table(index);
  323.     make_tasv(pref, t_oparray, opt->attrs, index,
  324.                   const_refs, (opt->table.value.const_refs
  325.                                + index - opt->base_index));
  326. }
  327.  
  328. /* Get an element from an array of some kind. */
  329. /* This is also used to index into Encoding vectors, */
  330. /* the error name vector, etc. */
  331. int
  332. array_get(const ref *aref, long index_long, ref *pref)
  333. {    if ( (ulong)index_long >= r_size(aref) )
  334.         return_error(e_rangecheck);
  335.     switch ( r_type(aref) )
  336.        {
  337.     case t_array:
  338.        {    const ref *pvalue =
  339.            aref->value.refs + (uint)index_long;
  340.         ref_assign(pref, pvalue);
  341.        }    return 0;
  342.     case t_mixedarray:
  343.        {    const ref_packed *packed = aref->value.packed;
  344.         uint index = (uint)index_long;
  345.         for ( ; index--; ) packed = packed_next(packed);
  346.         packed_get(packed, pref);
  347.        }    return 0;
  348.     case t_shortarray:
  349.        {    const ref_packed *packed =
  350.            aref->value.packed + (uint)index_long;
  351.         packed_get(packed, pref);
  352.        }    return 0;
  353.     default:
  354.         return_error(e_typecheck);
  355.        }
  356. }
  357.  
  358. /* Get an element from a packed array. */
  359. /* (This works for ordinary arrays too.) */
  360. /* Source and destination are allowed to overlap if the source is packed, */
  361. /* or if they are identical. */
  362. void
  363. packed_get(const ref_packed *packed, ref *pref)
  364. {    const ref_packed elt = *packed;
  365.     uint value = elt & packed_value_mask;
  366.     switch ( elt >> r_packed_type_shift )
  367.     {
  368.     default:            /* (shouldn't happen) */
  369.         make_null(pref);
  370.         break;
  371.     case pt_executable_operator:
  372.         op_index_ref(value, pref);
  373.         break;
  374.     case pt_integer:
  375.         make_int(pref, (int)value + packed_min_intval);
  376.         break;
  377.     case pt_literal_name:
  378.         name_index_ref(value, pref);
  379.         break;
  380.     case pt_executable_name:
  381.         name_index_ref(value, pref);
  382.         r_set_attrs(pref, a_executable);
  383.         break;
  384.     case pt_full_ref:
  385.     case pt_full_ref+1:
  386.         ref_assign(pref, (const ref *)packed);
  387.     }
  388. }
  389.  
  390. /* Check to make sure an interval contains no object references */
  391. /* to a space younger than a given one. */
  392. /* Return 0 or e_invalidaccess. */
  393. int
  394. refs_check_space(register const ref *bot, register uint size, uint space)
  395. {    for ( ; size--; bot++ )
  396.       store_check_space(space, bot);
  397.     return 0;
  398. }
  399.  
  400. /* ------ String utilities ------ */
  401.  
  402. /* Convert a C string to a Ghostscript string */
  403. int
  404. string_to_ref(const char *cstr, ref *pref, gs_ref_memory_t *mem,
  405.   client_name_t cname)
  406. {    uint size = strlen(cstr);
  407.     int code = gs_alloc_string_ref(mem, pref, a_all, size, cname);
  408.     if ( code < 0 )
  409.       return code;
  410.     memcpy(pref->value.bytes, cstr, size);
  411.     return 0;
  412. }
  413.  
  414. /* Convert a Ghostscript string to a C string. */
  415. /* Return 0 iff the buffer can't be allocated. */
  416. char *
  417. ref_to_string(const ref *pref, gs_memory_t *mem, client_name_t cname)
  418. {    uint size = r_size(pref);
  419.     char *str = (char *)gs_alloc_string(mem, size + 1, cname);
  420.     if ( str == 0 )
  421.         return 0;
  422.     memcpy(str, (const char *)pref->value.bytes, size);
  423.     str[size] = 0;
  424.     return str;
  425. }
  426.  
  427. /* ------ Operand utilities ------ */
  428.  
  429. /* Get N numeric operands from the stack or an array. */
  430. /* Return a bit-mask indicating which ones are integers, */
  431. /* or a (negative) error indication. */
  432. /* The 1-bit in the bit-mask refers to the first operand. */
  433. /* Store float versions of the operands at pval. */
  434. /* The stack underflow check (check for t__invalid) is harmless */
  435. /* if the operands come from somewhere other than the stack. */
  436. int
  437. num_params(const ref *op, int count, double *pval)
  438. {    int mask = 0;
  439.  
  440.     pval += count;
  441.     while ( --count >= 0 )
  442.        {    mask <<= 1;
  443.         switch ( r_type(op) )
  444.            {
  445.         case t_real:
  446.             *--pval = op->value.realval;
  447.             break;
  448.         case t_integer:
  449.             *--pval = op->value.intval;
  450.             mask++;
  451.             break;
  452.         case t__invalid:
  453.             return_error(e_stackunderflow);
  454.         default:
  455.             return_error(e_typecheck);
  456.            }
  457.         op--;
  458.        }
  459.     /* If count is very large, mask might overflow. */
  460.     /* In this case we clearly don't care about the value of mask. */
  461.     return (mask < 0 ? 0 : mask);
  462. }
  463. /* float_params doesn't bother to keep track of the mask. */
  464. int
  465. float_params(const ref *op, int count, float *pval)
  466. {    for ( pval += count; --count >= 0; --op )
  467.       switch ( r_type(op) )
  468.         {
  469.         case t_real:
  470.         *--pval = op->value.realval;
  471.         break;
  472.         case t_integer:
  473.         *--pval = op->value.intval;
  474.         break;
  475.         case t__invalid:
  476.         return_error(e_stackunderflow);
  477.         default:
  478.         return_error(e_typecheck);
  479.         }
  480.     return 0;
  481. }
  482.  
  483. /* Get a single real parameter. */
  484. /* The only possible error is e_typecheck. */
  485. /* If an error is returned, the return value is not updated. */
  486. int
  487. real_param(const ref *op, double *pparam)
  488. {    switch ( r_type(op) )
  489.        {
  490.        case t_integer:
  491.         *pparam = op->value.intval;
  492.         break;
  493.        case t_real:
  494.         *pparam = op->value.realval;
  495.         break;
  496.        default:
  497.         return_error(e_typecheck);
  498.        }
  499.     return 0;
  500. }
  501. int
  502. float_param(const ref *op, float *pparam)
  503. {    double dval;
  504.     int code = real_param(op, &dval);
  505.  
  506.     if ( code >= 0 )
  507.       *pparam = (float)dval; /* can't overflow */
  508.     return code;
  509. }
  510.  
  511. /* Get an integer parameter in a given range. */
  512. int
  513. int_param(const ref *op, int max_value, int *pparam)
  514. {    check_int_leu(*op, max_value);
  515.     *pparam = (int)op->value.intval;
  516.     return 0;
  517. }
  518.  
  519. /* Make real values on the operand stack. */
  520. int
  521. make_reals(ref *op, const double *pval, int count)
  522. {    /* This should return e_limitcheck if any real is too large */
  523.     /* to fit into a float on the stack. */
  524.     for ( ; count--; op++, pval++ )
  525.       make_real(op, *pval);
  526.     return 0;
  527. }
  528. int
  529. make_floats(ref *op, const float *pval, int count)
  530. {    /* This should return e_limitcheck for infinities. */
  531.     for ( ; count--; op++, pval++ )
  532.       make_real(op, *pval);
  533.     return 0;
  534. }
  535.  
  536. /* Compute the error code when check_proc fails. */
  537. /* Note that the client, not this procedure, uses return_error. */
  538. /* The stack underflow check is harmless in the off-stack case. */
  539. int
  540. check_proc_failed(const ref *pref)
  541. {    return (r_is_array(pref) ? e_invalidaccess :
  542.         r_has_type(pref, t__invalid) ? e_stackunderflow :
  543.         e_typecheck);
  544. }
  545.  
  546. /* Compute the error code when a type check on the stack fails. */
  547. /* Note that the client, not this procedure, uses return_error. */
  548. int
  549. check_type_failed(const ref *op)
  550. {    return (r_has_type(op, t__invalid) ? e_stackunderflow : e_typecheck);
  551. }
  552.  
  553. /* ------ Matrix utilities ------ */
  554.  
  555. /* Read a matrix operand. */
  556. /* Return 0 if OK, error code if not. */
  557. int
  558. read_matrix(const ref *op, gs_matrix *pmat)
  559. {    int code;
  560.     ref values[6];
  561.     const ref *pvalues;
  562.  
  563.     if ( r_has_type(op, t_array) )
  564.       pvalues = op->value.refs;
  565.     else
  566.       { int i;
  567.         for ( i = 0; i < 6; ++i )
  568.           { code = array_get(op, (long)i, &values[i]);
  569.             if ( code < 0 )
  570.           return code;
  571.           }
  572.         pvalues = values;
  573.       }
  574.     check_read(*op);
  575.     if ( r_size(op) != 6 )
  576.       return_error(e_rangecheck);
  577.     code = float_params(pvalues + 5, 6, (float *)pmat);
  578.     return (code < 0 ? code : 0);
  579. }
  580.  
  581. /* Write a matrix operand. */
  582. /* Return 0 if OK, error code if not. */
  583. int
  584. write_matrix(register ref *op, const gs_matrix *pmat)
  585. {    ref *aptr;
  586.     const float *pel;
  587.     int i;
  588.  
  589.     check_write_type(*op, t_array);
  590.     if ( r_size(op) != 6 )
  591.       return_error(e_rangecheck);
  592.     aptr = op->value.refs;
  593.     pel = (const float *)pmat;
  594.     for ( i = 5; i >= 0; i--, aptr++, pel++ )
  595.       {    ref_save(op, aptr, "write_matrix");
  596.         make_real_new(aptr, *pel);
  597.       }
  598.     return 0;
  599. }
  600.